#include "device_mgr.h"

#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>

#include <string.h>
#include "los_task.h" // 根据实际路径调整

#include "iot_errno.h"
#include "iot_i2c.h"
#include "iot_pwm.h"
#include "iot_gpio.h"

#include "lcd.h"
#include "picture.h"
#include "door.h"
#include "device_mgr.h"
#include "ws2812.h"

bool g_is_lcd_init = false;

bool g_is_entry_door_open = false;
bool g_is_garage_door_open = false;
bool g_is_window_open = false;
bool g_is_light_on = false;

void i2c_dev_init(void)
{
    printf("i2c_dev_init enter...\n");

    IoTI2cInit(I2C_HANDLE, EI2C_FRE_400K);

    // 光照传感器初始化
    uint8_t send_data[3] = {0x01};
    uint32_t send_len = 1;
    uint32_t ret = LzI2cWrite(I2C_HANDLE, BH1750_I2C_ADDRESS, send_data, send_len);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("+++++++++BH1750 init failed+++++++++\n");
    }

    // 矩阵键盘初始化
    send_data[0] = 0xFF;
    send_len = 1;
    ret = LzI2cWrite(I2C_HANDLE, KEYBOARD_I2C_ADDRESS, send_data, send_len);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("+++++++++Keyboard init failed+++++++++\n");
    }

    // 温湿度传感器初始化
    // 传感器软复位
    LOS_TaskDelay(20);
    memset(send_data, 0, sizeof(send_data));
    send_data[0] = 0xBA;
    send_len = 1;
    ret = LzI2cWrite(I2C_HANDLE, AHT20_I2C_ADDRESS, send_data, send_len);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("+++++++++AHT20 reset failed: %d+++++++++\n", ret);
    }

    // 传感器校准
    LOS_TaskDelay(100);
    send_data[0] = 0xBE;
    // send_data[1] = 0x08;
    // send_data[2] = 0x00;
    send_len = 1;
    ret = LzI2cWrite(I2C_HANDLE, AHT20_I2C_ADDRESS, send_data, send_len);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("+++++++++AHT20 carlibrate failed: %d+++++++++\n", ret);
    }
}

void gpio_dev_init(void)
{
    // 风扇控制引脚初始化
    IoTGpioInit(MOTOR_PWM_B1A);
    IoTGpioSetDir(MOTOR_PWM_B1A, IOT_GPIO_DIR_OUT);
    IoTGpioSetOutputVal(MOTOR_PWM_B1A, IOT_GPIO_VALUE0);
    IoTGpioInit(MOTOR_PWM_B2A);
    IoTGpioSetDir(MOTOR_PWM_B2A, IOT_GPIO_DIR_OUT);
    IoTGpioSetOutputVal(MOTOR_PWM_B2A, IOT_GPIO_VALUE0);

    // IoTGpioInit(LIGHT_CTL_PIN);
    // IoTGpioSetDir(LIGHT_CTL_PIN, IOT_GPIO_DIR_OUT);
    // IoTGpioSetOutputVal(LIGHT_CTL_PIN, IOT_GPIO_VALUE0);
}
int door_init(void)
{
    sg90_init(DOOR_ENTRY_PIN);
    sg90_init(DOOR_GARAGE_PIN);
    sg90_init(WINDOW_PIN);
    door_actuator_control();
    return 0;
}

/***************************************************************
 * 函数名称: light_dev_init
 * 说    明: rgb灯设备初始化
 * 参    数: 无
 * 返 回 值: 无
 ***************************************************************/
void light_dev_init(void)
{
    ws281x_init(ESPI1_M1);
}

void lcd_dev_init(void)
{
    lcd_init();
    lcd_fill(0, 0, LCD_W, LCD_H, LCD_WHITE);
}

void lcd_load_ui(void)
{
    float t = 0;
    uint8_t cur_sizey = 12;
    // lcd_show_chinese(81, 0, (uint8_t*)"智慧小屋", LCD_BLUE, LCD_WHITE, 32, 0);
    printf("************load UI***********\n");
    lcd_show_picture(50, 0, 135, 40, &gImage_company_logo[0]);
    lcd_draw_line(0, 42, LCD_W, 42, LCD_DARKBLUE);
    // lcd_show_string(32, 45, "Smart House", LCD_RED, LCD_WHITE, 32, 0);
    lcd_show_chinese(56, 45, "智慧小屋", LCD_RED, LCD_WHITE, 32, 0);
    lcd_draw_line(0, 78, LCD_W, 78, LCD_DARKBLUE);
    // lcd_show_string(0, 80, "Temperature  : ", LCD_BLUE, LCD_WHITE, 16, 0);
    lcd_show_chinese(0, 80, "温度：", LCD_BLUE, LCD_WHITE, 16, 0);
    // lcd_show_string(0, 100, "Humidity     : ", LCD_BLUE, LCD_WHITE, 16, 0);
    lcd_show_chinese(0, 100, "湿度：", LCD_BLUE, LCD_WHITE, 16, 0);
    // lcd_show_string(0, 120, "Illumination : ", LCD_BLUE, LCD_WHITE, 16, 0);
    lcd_show_chinese(0, 120, "光强：", LCD_BLUE, LCD_WHITE, 16, 0);
    lcd_draw_line(0, 160, LCD_W, 160, LCD_DARKBLUE);
    // lcd_show_string(0, 165, "Entry door  : OFF", LCD_BRED, LCD_WHITE, 16, 0);
    lcd_show_chinese(0, 165, "入户门：关", LCD_BRED, LCD_WHITE, 16, 0);
    // lcd_show_string(0, 185, "Garage door : OFF", LCD_BRED, LCD_WHITE, 16, 0);
    lcd_show_chinese(0, 185, "车库门：关", LCD_BRED, LCD_WHITE, 16, 0);
    // lcd_show_string(0, 205, "Window      : OFF", LCD_BRED, LCD_WHITE, 16, 0);
    lcd_show_chinese(16, 205, "窗户：关", LCD_BRED, LCD_WHITE, 16, 0);
    // lcd_show_string(0, 230, "Light       : OFF", LCD_BRED, LCD_WHITE, 16, 0);
    lcd_show_chinese(16, 230, "灯光：关", LCD_BRED, LCD_WHITE, 16, 0);
    lcd_draw_line(0, 285, LCD_W, 285, LCD_DARKBLUE);
    // lcd_show_int_num(48, 160, LCD_W, 3, LCD_BLUE, LCD_WHITE, 16);
    // lcd_show_string(80, 160, "LCD_H:", LCD_BLUE, LCD_WHITE, 16, 0);
    // lcd_show_int_num(128, 160, LCD_H, 3, LCD_BLUE, LCD_WHITE, 16);
    // lcd_show_string(80, 160, "LCD_H:", LCD_BLUE, LCD_WHITE, 16, 0);
    // lcd_show_string(0, 190, "Increaseing Num:", LCD_BLACK, LCD_WHITE, 16, 0);
    // lcd_show_float_num1(128, 190, t, 4, LCD_BLACK, LCD_WHITE, 16);
    t += 0.11;

    // lcd_fill(0, 0, LCD_W, LCD_H, LCD_WHITE);

    g_is_lcd_init = true;
}

void lcd_set_human_state(bool state)
{
    if (state)
    {
        lcd_show_chinese(120, 75, (uint8_t *)"有人", LCD_RED, LCD_WHITE, 24, 0);
    }
    else
    {
        lcd_show_chinese(120, 75, (uint8_t *)"无人", LCD_RED, LCD_WHITE, 24, 0);
    }
}

void lcd_set_light_state(bool state)
{
    if (state)
    {
        lcd_show_chinese(120, 120, (uint8_t *)"开", LCD_RED, LCD_WHITE, 24, 0);
    }
    else
    {
        lcd_show_chinese(120, 120, (uint8_t *)"关", LCD_RED, LCD_WHITE, 24, 0);
    }
}

void lcd_set_auto_state(bool state)
{
    if (state)
    {
        lcd_show_chinese(120, 150, (uint8_t *)"开", LCD_RED, LCD_WHITE, 24, 0);
    }
    else
    {
        lcd_show_chinese(120, 150, (uint8_t *)"关", LCD_RED, LCD_WHITE, 24, 0);
    }
}

void delay_us(uint32_t us)
{
    LOS_TaskDelay(us);
}

bool body_induction_get_state()
{
    IotGpioValue value = IOT_GPIO_VALUE0;

    if (value)
    {
        return true;
    }
    else
    {
        return false;
    }

    printf("body_induction_get_state: %d\n", value);
}
void body_induction_dev_init(void)
{
}

uint32_t mq2_dev_init(iss_mq2_dev_s *adc)
{
    if (PinctrlInit(adc->adc) != 0)
    {
        printf("adc pin %d init failed\n", adc->adc.gpio);
        return 1;
    }
    if (LzSaradcInit() != 0)
    {
        printf("saradc  %d init failed\n", adc->port);
        return 1;
    }

    volatile GRF_SOC_CON29 *soc = (GRF_SOC_CON29 *)&GRF->SOC_CON29;
    /*配置ADC外部参考电压grf_saradc_vol_sel=0，内部参考电压grf_saradc_vol_sel=1,rw.grf_saradc_vol_sel对应位写使能*/
    soc->grf_saradc_vol_sel = 1;
    soc->grf_saradc_vol_sel = 0;
    soc->grf_saradc_vol_sel = 0;

    adc->init = 1;
    return 0;
}
int adc_get_voltage(int pin, float *voltage)
{
    unsigned int ret = IOT_SUCCESS;
    unsigned int data = 0;

    ret = IoTAdcGetVal(pin, &data);
    if (ret != IOT_SUCCESS)
    {
        printf("%s, %s, %d: ADC Read Fail\n", __FILE__, __func__, __LINE__);
        return -1;
    }

    *voltage = (data * 3.3 / 1024.0);
    printf("adc_get_voltage. voltage = %d", data);
    return 0;
}

int get_mq2_ppm(float *ppm)
{
    float voltage = 0.0;
    int ret = adc_get_voltage(MQ2_PIN, &voltage);
    if (ret != 0)
    {
        *ppm = voltage;
        printf("get_mq2_ppm: get voltage failed\n");
        return -1;
    }
    float rs = (5 - voltage) / voltage * RL;
    float m_r0 = rs / powf(CAL_PPM / 613.9f, 1 / -2.074f);
    *ppm = powf(m_r0 / rs, 2.074f) * 613.9f;

    return 0;
}

int get_light_value(float *lux)
{
    // 启动光照传感器
    uint8_t send_data[1] = {0x10};
    uint32_t send_len = 1;
    uint32_t ret = LzI2cWrite(I2C_HANDLE, BH1750_I2C_ADDRESS, send_data, send_len);
    LOS_Msleep(180); // 等待传感器稳定

    // 读取光照值
    uint8_t recv_data[2] = {0};
    uint32_t receive_len = 2;
    ret |= LzI2cRead(I2C_HANDLE, BH1750_I2C_ADDRESS, recv_data, receive_len);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("+++++++++BH1750 I2C read error: %d+++++++++\n", ret);
        return -1;
    }

    *lux = (float)(((recv_data[0] << 8) + recv_data[1]) / 1.2);

    // LCD 显示光照强度值
    if (g_is_lcd_init)
    {
        char ill_value[16] = {0};
        sprintf(ill_value, "%d lux  ", (int)*lux);
        lcd_show_string(50, 120, ill_value, LCD_BLUE, LCD_WHITE, 16, 0);
    }

    return 0;
}

int get_tmp_hum_value(float *temperature, float *humidity)
{
    // 启动温湿度传感器
    uint8_t send_data[3] = {0xAC, 0x33, 0x00};
    uint32_t send_len = 3;
    uint32_t ret = LzI2cWrite(I2C_HANDLE, AHT20_I2C_ADDRESS, send_data, send_len);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("+++++++++AHT20 I2C start read error: %d+++++++++\n", ret);
        return ret;
    }
    LOS_Msleep(180); // 等待传感器稳定

    // 读取温湿度值
    uint8_t recv_data[6] = {0};
    uint32_t receive_len = 6;
    ret |= LzI2cRead(I2C_HANDLE, AHT20_I2C_ADDRESS, recv_data, receive_len);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("+++++++++AHT20 I2C read error: %d+++++++++\n", ret);
        return ret;
    }
    uint32_t humidity_raw = ((uint32_t)recv_data[1] << 12) | ((uint32_t)recv_data[2] << 4) | (recv_data[3] >> 4);
    uint32_t temp_raw = (((uint32_t)recv_data[3] & 0x0F) << 16) | ((uint32_t)recv_data[4] << 8) | recv_data[5];

    // 转换为实际值（根据AHT20数据手册公式）
    *humidity = (humidity_raw / 1048576.0f) * 100.0f; // 1048576 = 2^20
    *temperature = (temp_raw / 1048576.0f) * 200.0f - 50.0f;

    // LCD 显示温湿度值
    if (g_is_lcd_init)
    {
        char tmp_value[16] = {0};
        sprintf(tmp_value, "%.2f ", *temperature);
        lcd_show_string(50, 80, tmp_value, LCD_BLUE, LCD_WHITE, 16, 0);
        lcd_show_chinese(100, 80, "℃", LCD_BLUE, LCD_WHITE, 16, 0);

        char hum_value[16] = {0};
        sprintf(hum_value, "%.2f", *humidity);
        lcd_show_string(50, 100, hum_value, LCD_BLUE, LCD_WHITE, 16, 0);
        lcd_show_chinese(100, 100, "％", LCD_BLUE, LCD_WHITE, 16, 0);
    }

    return 0;
}

int get_smoke_value(float *ppm)
{
    return 0;
}

/* I2C读写函数 */
void pcf8574_write(uint8_t data)
{
    uint8_t send_data[1] = {data};
    IoTI2cWrite(I2C_HANDLE, KEYBOARD_I2C_ADDRESS, send_data, 1);
    LOS_Msleep(1);
}

uint8_t pcf8574_read(void)
{
    uint8_t data = 0;
    IoTI2cRead(I2C_HANDLE, KEYBOARD_I2C_ADDRESS, &data, 1);
    LOS_Msleep(1);
    return data;
}
int get_key_pressed(char *key)
{
    uint32_t current_time = LOS_TickCountGet();
    uint8_t col_val;
    char new_key = '\0';
    DebounceState debounce_state = DEBOUNCE_STATE_IDLE;
    uint32_t last_debounce_time = 0;
    char debounce_key = '\0';

    const char keys[KEYPAD_ROWS][KEYPAD_COLS] = {
        {'1', '2', '3', 'A'},
        {'4', '5', '6', 'B'},
        {'7', '8', '9', 'C'},
        {'*', '0', '#', 'D'}};

    // 扫描键盘
    for (uint8_t row = 0; row < KEYPAD_ROWS; row++)
    {
        pcf8574_write(~(1 << row));
        col_val = pcf8574_read() >> 4;

        for (uint8_t col = 0; col < KEYPAD_COLS; col++)
        {
            if (!(col_val & (1 << col)))
            {
                new_key = keys[row][col];
                break;
            }
        }
        if (new_key != '\0')
        {
            debounce_key = DEBOUNCE_STATE_PRESS_DETECTED;
            break;
        }
    }
    // printf("key pressed: %c\n", new_key);
    *key = new_key;

    // 消抖处理
    switch (debounce_state) {
        case DEBOUNCE_STATE_IDLE:
            if (new_key != '\0') {
                debounce_key = new_key;
                last_debounce_time = current_time;
                debounce_state = DEBOUNCE_STATE_PRESS_DETECTED;
            }
            break;

        case DEBOUNCE_STATE_PRESS_DETECTED:
            if (new_key == debounce_key) {
                if ((current_time - last_debounce_time) >= LOS_MS2Tick(DEBOUNCE_DELAY_MS)) {
                    debounce_state = DEBOUNCE_STATE_WAIT_RELEASE;
                    *key = debounce_key;
                    return 0;
                }
            } else {
                debounce_state = DEBOUNCE_STATE_IDLE;
            }
            break;

        case DEBOUNCE_STATE_WAIT_RELEASE:
            if (new_key == '\0') {
                debounce_state = DEBOUNCE_STATE_IDLE;
            }
            break;
    }

    return 0;
}

// static void ws2812b_send_bit(uint8_t bit)
// {
//     if (bit)
//     {
//         IoTGpioSetOutputVal(LIGHT_CTL_PIN, IOT_GPIO_VALUE1);
//         delay_us(7); // T1H = ~700ns
//         IoTGpioSetOutputVal(LIGHT_CTL_PIN, IOT_GPIO_VALUE0);
//         delay_us(6); // T1L = ~600ns
//     }
//     else
//     {
//         IoTGpioSetOutputVal(LIGHT_CTL_PIN, IOT_GPIO_VALUE1);
//         delay_us(3); // T0H = ~350ns
//         IoTGpioSetOutputVal(LIGHT_CTL_PIN, IOT_GPIO_VALUE0);
//         delay_us(8); // T0L = ~800ns
//     }
// }

// static void ws2812b_send_byte(uint8_t byte)
// {
//     for (int i = 7; i >= 0; i--)
//     {
//         ws2812b_send_bit((byte >> i) & 0x01);
//     }
// }

// static void ws2812b_send_color(uint32_t color, int num_leds)
// {
//     for (int i = 0; i < num_leds; i++)
//     {
//         // GRB顺序发送
//         uint8_t green = (color >> 16) & 0xFF;
//         uint8_t red = (color >> 8) & 0xFF;
//         uint8_t blue = (color >> 0) & 0xFF;

//         ws2812b_send_byte(green);
//         ws2812b_send_byte(red);
//         ws2812b_send_byte(blue);
//     }
//     // LOS_TaskDelay(5000);

//     // 发送结束信号（低电平持续50us以上）
//     // IoTGpioSetOutputVal(LIGHT_CTL_PIN, IOT_GPIO_VALUE0);
//     delay_us(50);
// }

int light_control()
{
    // printf("light_control enter...");
    static bool last_state = false;
    printf("g_is_light_on: %d, last_state: %d\n", g_is_light_on, last_state);

    if (g_is_light_on == last_state)
    {
        return 0;
    }

    ws2812x_set_light_sta(10, g_is_light_on);

    last_state = g_is_light_on;

    lcd_fill(110, 230, 200, 250, LCD_WHITE); // 清除之前的状态显示
    // lcd_show_string(112, 230, g_is_light_on ? "ON" : "OFF", LCD_BRED, LCD_WHITE, 16, 0);
    lcd_show_string(70, 230, g_is_light_on ? "开" : "关", LCD_BRED, LCD_WHITE, 16, 0);

    return 0;
}

int door_control(int pin, sg90_angel_e angle)
{
    printf("door_control enter...\n");

    return sg90_set_angel(pin, angle);
}

int door_actuator_control(void)
{
    // 控制门锁舵机
    sg90_angel_e angle = SG90_ANGEL_0;
    int ret = 0;

    static bool entry_sta = false, garage_sta = false, wind_sta = false;
    if (entry_sta != g_is_entry_door_open)
    {
        angle = g_is_entry_door_open == true ? SG90_ANGEL_180 : SG90_ANGEL_90;
        ret = door_control(DOOR_ENTRY_PIN, angle);
        if (ret == 0)
        {
            lcd_fill(110, 165, 200, 185, LCD_WHITE); // 清除之前的状态显示
            // 显示新的状态 
            // lcd_show_string(112, 165, g_is_entry_door_open ? "ON" : "OFF", LCD_BRED, LCD_WHITE, 16, 0);
            lcd_show_string(70, 165, g_is_entry_door_open ? "开" : "关", LCD_BRED, LCD_WHITE, 16, 0);
            entry_sta = g_is_entry_door_open;
        }
    }

    if (garage_sta != g_is_garage_door_open)
    {
        angle = g_is_garage_door_open == true ? SG90_ANGEL_90 : SG90_ANGEL_0;
        ret = door_control(DOOR_GARAGE_PIN, angle);
        if (ret == 0)
        {
            lcd_fill(110, 185, 200, 205, LCD_WHITE); // 清除之前的状态显示
            // 显示新的状态
            // lcd_show_string(112, 185, g_is_garage_door_open ? "ON" : "OFF", LCD_BRED, LCD_WHITE, 16, 0);
            lcd_show_string(70, 185, g_is_garage_door_open ? "开" : "关", LCD_BRED, LCD_WHITE, 16, 0);
            garage_sta = g_is_garage_door_open;
        }
    }

    if (wind_sta != g_is_window_open)
    {
        angle = g_is_window_open == true ? SG90_ANGEL_90 : SG90_ANGEL_180;
        ret = door_control(WINDOW_PIN, angle);
        if (ret == 0)
        {
            lcd_fill(110, 205, 200, 225, LCD_WHITE); // 清除之前的状态显示
            // 显示新的状态
            // lcd_show_string(112, 205, g_is_window_open ? "ON" : "OFF", LCD_BRED, LCD_WHITE, 16, 0);
            lcd_show_string(70, 205, g_is_window_open ? "开" : "关", LCD_BRED, LCD_WHITE, 16, 0);
            wind_sta = g_is_window_open;
        }
    }

    if (ret != 0)
    {
        printf("door control failed. ", ret);
    }

    return 0; // 操作成功
}
